package models

import (
	"errors"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	_ "github.com/go-sql-driver/mysql"
	"strconv"
	"strings"
	"time"
)

type IpccConfBasicVoice struct {
	Id            int
	AppId         string    `orm:"description(appId);"`
	WaitVoice     string    `orm:"description(等待语音);"`
	EndVoice      string    `orm:"description(挂机语音);"`
	OffWorkVoice  string    `orm:"description(下班语音);"`
	BOffWorkLeave string    `orm:"description(下班留言开关);"`
	LeaveVoice    string    `orm:"description(留言语音);"`
	LeaveSwitch   bool      `orm:"description(留言开关);"`
	PlayTimes     int       `orm:"description(播放次数);"`
	StopSecond    int       `orm:"description(停顿时间,单位：秒);"`
	PlayServiceId string    `orm:"description(播放坐席工号);null;"`
	CreateTime    time.Time `orm:"auto_now_add; type(datetime)"`
	UpdateTime    time.Time `orm:"auto_now_add; type(datetime)"`
}

type IpccFixedNumber struct {
	Id           int
	FixedNumber  string    `orm:"description(企业号码);"`
	DeveloperId  int       `orm:"description(企业Id);"`
	CreateTime   time.Time `orm:"auto_now_add; type(datetime)"`
	Display      int       `orm:"column(display)"`
	CallIn       int       `orm:"column(callin)"`
	TransferType int       `orm:"column(transfer_type)"`
	TransferId   int       `orm:"column(transfer_id)"`
}

type IpccConfCompany struct {
	Id               int       `orm:"pk;auto"`
	AppId            string    `orm:"description(企业Id);"`
	Number           string    `orm:"description(服务号码)"`
	NavAudio         string    `orm:"description(导航语音)"`
	Acd              string    `orm:"description(分配模式)"`
	GetKey           bool      `orm:"default(true);description(按键支持，默认开启)"`
	Satisfaction     string    `orm:"description(满意度调查);null"`
	SatisfactionTip  string    `orm:"description(满意度调查,提示音);null"`
	SatisfactionAuto string    `orm:"description(满意度调查,自动发送);null"`
	BasicConf        string    `orm:"description(基础配置);null;"`
	EndVoice         string    `orm:"description(挂机结束音);null"`
	CreateTime       time.Time `orm:"auto_now_add; type(datetime)"`
}

func RegisterCompany() {
	orm.RegisterModel(new(IpccConfCompany), new(IpccFixedNumber), new(IpccConfBasicVoice))
}

func StoreOffWork(appId, offwork, leaveVoice, leaveMsg string) {

	newBasic := IpccConfBasicVoice{
		AppId:         appId,
		OffWorkVoice:  offwork,
		LeaveVoice:    leaveVoice,
		UpdateTime:    time.Now(),
		BOffWorkLeave: leaveMsg,
	}

	oldBasic := newBasic

	o := orm.NewOrm()

	err := o.QueryTable(new(IpccConfBasicVoice)).Filter("AppId", appId).One(&oldBasic)
	if err == nil {
		newBasic.Id = oldBasic.Id
		if len(offwork) > 0 {
			_, err = o.Update(&newBasic, "OffWorkVoice", "UpdateTime")
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		}

		if len(leaveVoice) > 0 {
			_, err = o.Update(&newBasic, "LeaveVoice", "UpdateTime")
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		}

		if len(leaveMsg) > 0 {
			_, err = o.Update(&newBasic, "BOffWorkLeave", "UpdateTime")
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		}

	} else {
		if strings.Contains(err.Error(), "found") {
			_, err := o.Insert(&newBasic)
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		} else {
			logs.Error("读取数据[%v]失败:%v", appId, err)
		}
	}
}

func StoreBasicVoice(appId, waitVoice, endVoice string, playTimes, stopSecd int, bleaveMsg bool) {

	newBasic := IpccConfBasicVoice{
		AppId:       appId,
		WaitVoice:   waitVoice,
		EndVoice:    endVoice,
		PlayTimes:   playTimes,
		StopSecond:  stopSecd,
		LeaveSwitch: bleaveMsg,
		UpdateTime:  time.Now(),
	}

	oldBasic := newBasic

	o := orm.NewOrm()

	err := o.QueryTable(new(IpccConfBasicVoice)).Filter("AppId", appId).One(&oldBasic)
	if err == nil {
		newBasic.Id = oldBasic.Id

		_, err = o.Update(&newBasic, "WaitVoice", "EndVoice", "PlayTimes", "StopSecond", "LeaveSwitch", "UpdateTime")
		if err != nil {
			logs.Error("store err:%v :%v", err.Error(), newBasic)
		}
	} else {
		if strings.Contains(err.Error(), "found") {
			_, err := o.Insert(&newBasic)
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		} else {
			logs.Error("读取数据[%v]失败:%v", appId, err)
		}
	}
}

func StorePlayServiceId(appId, args string) {

	newBasic := IpccConfBasicVoice{
		AppId:         appId,
		PlayServiceId: args,
		UpdateTime:    time.Now(),
	}

	oldBasic := newBasic
	o := orm.NewOrm()

	err := o.Read(&oldBasic, "AppId")
	if err == nil {
		newBasic.Id = oldBasic.Id
		_, err = o.Update(&newBasic, "PlayServiceId", "UpdateTime")
		if err != nil {
			logs.Error("store err:%v :%v", err.Error(), newBasic)
		}
	} else {
		if strings.Contains(err.Error(), "found") {
			_, err := o.Insert(&newBasic)
			if err != nil {
				logs.Error("store err:%v :%v", err.Error(), newBasic)
			}
		} else {
			logs.Error("读取数据[%v]失败:%v", appId, err)
		}
	}

}

func LoadBasicVoice(appId string) (IpccConfBasicVoice, error) {
	basicVoice := IpccConfBasicVoice{
		AppId: appId,
	}
	o := orm.NewOrm()

	err := o.Read(&basicVoice, "AppId")
	return basicVoice, err
}

func StoreNewCompany(appId, navAudio, number, acd string, getKey bool) error {

	newCompny := IpccConfCompany{
		AppId:      appId,
		Number:     number,
		NavAudio:   navAudio,
		GetKey:     getKey,
		Acd:        acd,
		CreateTime: time.Now(),
	}

	o := orm.NewOrm()

	create, _, err := o.ReadOrCreate(&newCompny, "AppId")
	if err == nil {
		if create {

		} else {

		}
	} else {
		logs.Error("store err:%v ", err)
	}

	return err
}

func UpdateCompanySatisfaction(appId, active, auto, tips, endvoice string) error {

	newCompny := &IpccConfCompany{
		AppId: appId,
	}

	o := orm.NewOrm()

	err := o.QueryTable("IpccConfCompany").Filter("AppId", appId).One(newCompny)
	if err == nil {

		if len(active) > 0 {
			newCompny.Satisfaction = active
		}

		if len(tips) > 0 {
			newCompny.SatisfactionTip = tips
		}

		if len(auto) > 0 {
			newCompny.SatisfactionAuto = auto
		}

		if len(endvoice) > 0 {
			newCompny.EndVoice = endvoice
		}

		_, err = o.Update(newCompny, "Satisfaction", "SatisfactionTip", "SatisfactionAuto", "EndVoice")
	} else {
		newCompny = &IpccConfCompany{
			AppId:            appId,
			Satisfaction:     active,
			SatisfactionTip:  tips,
			SatisfactionAuto: auto,
			EndVoice:         endvoice,
			CreateTime:       time.Now(),
		}
		_, err = o.Insert(newCompny)
	}

	if err != nil {
		logs.Error("[%v] 满意度更新失败:%v", appId, err)
	}
	return err
}

/*
func AddNewNumber(companyId, number string) error {

	id, err := strconv.Atoi(companyId)
	if err != nil {
		logs.Error("wrong company id:%v,err:%v", companyId, err)
		return err
	}

	newNumberConf := IpccFixedNumber{
		DeveloperId:   id,
		FixedNumber: number,

	}
	o := orm.NewOrm()

	create, _, err := o.ReadOrCreate(&newNumberConf, "Number")
	if err == nil {
		if create {
			return nil
		} else {
			if newNumberConf.Active == true {
				return fmt.Errorf("number %v is exist for company %v ", number, newNumberConf.CompanyId)
			} else {
				newNumberConf.CompanyId = id
				newNumberConf.Active = true
				_, err = o.Update(&newNumberConf)
				return err
			}
		}
	}
	return err
}
*/
func ReloadNumberForCompany(appId string) ([]IpccFixedNumber, error) {
	result := []IpccFixedNumber{}

	devId, _ := strconv.Atoi(appId)

	size := int64(1000)
	o := orm.NewOrm()
	for count := 0; ; count++ {

		numbers := []IpccFixedNumber{}
		n, err := o.QueryTable(new(IpccFixedNumber)).
			Filter("DeveloperId", devId).
			Limit(size, count).
			All(&numbers)
		if err != nil {
			return nil, err
		}

		result = append(result, numbers...)

		if n < size {
			break
		}
	}

	return result, nil
}

func UpdateCompany(appId, navAudio, number, acd string, getKey bool) error {

	appInfo := &IpccConfCompany{}

	o := orm.NewOrm()
	err := o.QueryTable("IpccConfCompany").Filter("AppId", appId).One(appInfo)
	if err != nil {
		logs.Error("appId[%v] 没有找到", appId)
		return fmt.Errorf("NoExist")
	}

	newCompny := &IpccConfCompany{
		Id:       appInfo.Id,
		AppId:    appId,
		NavAudio: navAudio,
		Acd:      acd,
		Number:   number,
	}

	if navAudio != "" {
		_, err = o.Update(newCompny, "NavAudio")
		if err != nil {
			return err
		}
	}

	if acd != "" {
		_, err = o.Update(newCompny, "Acd")
		if err != nil {
			return err
		}
	}

	if number != "" {
		_, err = o.Update(newCompny, "Number")
		if err != nil {
			return err
		}
	}

	return nil
}

func UpdateCompanyBasicData(appId, config string) {
	appInfo := &IpccConfCompany{}

	o := orm.NewOrm()
	err := o.QueryTable("IpccConfCompany").Filter("AppId", appId).One(appInfo)
	if err != nil {
		logs.Error("appId[%v] 没有找到", appId)
		return
	}

	appInfo.BasicConf = config
	_, err = o.Update(appInfo, "BasicConf")
	if err != nil {
		logs.Error("[%v]更新基础配置失败:%v，参数:%v", appId, err, config)
		return
	}
}

func LoadCompany(maxNum, count int) ([]*IpccConfCompany, error) {

	var res []*IpccConfCompany
	o := orm.NewOrm()

	n, err := o.QueryTable(new(IpccConfCompany)).Limit(maxNum).Offset(count * maxNum).All(&res)
	if n == 0 {
		logs.Info("No more company")
		return res, errors.New("EOF")
	}

	return res, err

}
